﻿using System;
using System.Collections.Generic;

namespace Inovout.Data.Redis
{
    public abstract class RedisConnection : RedisCommand, IDisposable
    {
        internal RedisCommandScriptExecutor Executor
        { get; private set; }
        private int dbId;
        protected RedisConnection(Uri serverUri, int dbId)
        {
            ConnectionString = serverUri;
            this.dbId = dbId;
            Connection = this;
        }
        public void Open()
        {
            //需增加一个有关的连接的状态
            Executor = new RedisCommandScriptExecutor(this);
            RedisCommandResult<bool> commandResult;
            Executor.CommandScripts.Add(RedisCommandScript.Create(this,RedisLiteral.Select, new RedisCommandParameter[]{(long)dbId}, out commandResult));
        }
        internal RedisCommandResult<bool> Select()
        {
            return Execute<bool>(RedisLiteral.Select, dbId);
        }
        public static RedisConnection Create(Uri serverUri, int dbId)
        {
            return new HttpRedisConnection(serverUri, dbId);
        }
        public StringCommand CreateStringCommand()
        {
            return CreateCommand<StringCommand>();
        }
        public KeyCommand CreateKeyCommand()
        {
            return CreateCommand<KeyCommand>();
        }
        private TCommand CreateCommand<TCommand>() where TCommand : RedisCommand, new()
        {
            TCommand command = new TCommand();
            command.Connection = this;
            return command;
        }

        public RedisTransaction BeginTransaction()
        {
            if (IsTransactionConnection)
            {
                throw new Exception("Transaction is created.");
            }
            IsTransactionConnection = true;
            return new RedisTransaction(this);
        }

        public virtual void Dispose()
        {
        }

        public bool IsTransactionConnection { get; private set; }

        public Uri ConnectionString { get; private set; }

        public void Close()
        {
            Executor.CommandScripts.Clear();
        }
    }
}
